package scuts.core.macros;

#if macro
import scuts.macro.Convert;
import haxe.macro.Compiler;
import scuts.macro.Check;
import scuts.macro.Extract;
import scuts.macro.Parse;
import scuts.macro.Print;
import scuts.macro.Make;
import haxe.macro.Context;
import haxe.macro.Expr;
using scuts.core.extensions.Options;
using scuts.core.Map;


class MakeArray {
  /*
   * returns
   * { 
   *   var arr:Array<BaseType> = [];
   *   arr.push(expr_1);
   *   ...
   *   arr.push(expr_N);
   *   arr;
   * } 
   * 
   * 
   * usage: [1,1.0].asArray(Float) => Array<Float>
   */
  public static function asArray (arr:ExprRequire<Array<Dynamic>>, baseType:Expr) {
    
    // baseType must be const String for or a Type
    
    var arrDecl = Extract.extractArrayDeclValues(arr);

    if (arrDecl.isNone()) {
      Context.error("Argument arr must be const array", arr.pos);
    } else {
      var validBaseType = Check.isConstString(baseType) || Check.isType(baseType);
      if (validBaseType) {
         var s = "{ var a:Array<$0> = [];" 
              + arrDecl.value().mapWithIndex(function (v, i) return "a.push($" + (i + 1) + ");").join("")
              + "a;}";
         
         var a:Array<Dynamic> = arrDecl.value().copy();
         a.unshift(baseType);
         var e = Parse.parse(s, a);
         trace(Print.exprStr(e));
         return e;
      } else {
        Context.error("Argument baseType must be a valid Type", arr.pos);
      }
      
    }
    
    return Make.mkEmptyBlock();
  }
}
#end